﻿namespace PlaylistCopy.Components
{
    using PlaylistCopy.Annotations;
    using PlaylistCopy.Contract;
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    using System.Linq;

    internal class PlaylistImporter : IPlaylistImporter
    {
        [ImportMany(typeof(IPlaylist)), UsedImplicitly]
        private IEnumerable<Lazy<IPlaylist>> playlistsCollection;

        private IReadOnlyCollection<IPlaylist> evaluatedPlaylists;

        private readonly ILogger logger;

        private bool imported;

        public PlaylistImporter(ILogger logger)
        {
            this.logger = logger;
        }

        public void Import()
        {
            if (this.imported)
            {
                throw new InvalidOperationException("Modules already imorted.");
            }

            var catalog = new ApplicationCatalog();
            var container = new CompositionContainer(catalog);

            this.PrepareLoggerImport(container);

            container.ComposeParts(this);
            this.imported = true;
        }

        private void PrepareLoggerImport(CompositionContainer container)
        {
            container.ComposeExportedValue("Logger", this.logger);
        }

        public int PlaylistsCount
        {
            get { return this.Query().Count(); }
        }

        public IEnumerable<IPlaylist> Query()
        {
            this.CheckImported();

            if (this.evaluatedPlaylists != null)
            {
                return this.evaluatedPlaylists;
            }

            var playlistList =
                this.playlistsCollection.Select(playlist => playlist.Value).Where(CheckPlaylistProvider).ToList();

            return (this.evaluatedPlaylists = new ReadOnlyCollection<IPlaylist>(playlistList));
        }

        private void CheckImported()
        {
            if (!imported)
            {
                this.Import();
            }
        }

        private static bool CheckPlaylistProvider(IPlaylist playlist)
        {
            if (playlist == null)
            {
                return false;
            }

            return !string.IsNullOrWhiteSpace(playlist.PlaylistExtension) && !playlist.PlaylistExtension.StartsWith(".") &&
                   !playlist.PlaylistExtension.StartsWith("*");
        }
    }
}
